package control;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JOptionPane;

import model.BestSolution;
import model.EqActiveCooling;
import model.EqCO2;
import model.EqCurtain;
import model.EqLight;
import model.EqSprinkler;
import model.EqTermostat;
import model.EqWindow;
import model.Equipment;
import model.House;
import model.Measurement;
import model.ModelClass;
import model.Plant;
import model.Section;
import model.Variables;
import model.Sensor.MainMindThread;
import view.CenterPanel;
import view.MainF;


public class FunktionMethods {
	MainF mainF;
	private CenterPanel centerPanel;
	private ModelClass modelClass;
	private Variables variables;
	private ThreadAuto threadAuto;

	public FunktionMethods(MainF mainF) {
		this.mainF = mainF;
		this.centerPanel = mainF.getCenter();
		this.modelClass = mainF.getModel();
		this.variables = modelClass.getVariables();
		this.threadAuto = new ThreadAuto(this.mainF);
		//Run methods to get some start-data into the system
		runACycle();
		runACycle();
		runACycle();
		runACycle();
	}
	
	// Method that expands and inspands the right panel
	public void expandRightPanel() {
		if (mainF.getRight().getBtnNewButton().getName().equals("Expand")) {
			mainF.getRight().getBtnNewButton().setName("Inspand");
			mainF.getRight().getBtnNewButton()
					.setIcon(mainF.getModel().getVariables().getImgInspand());

			for (int i = 0; i < 50; i++) {
				try {
					Thread.sleep(8);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				mainF.getRight().removeAll();
				mainF.getRight().setPreferredSize(
						new Dimension(50 + i * 3, 690));
				mainF.pack();
				mainF.getRight().paint(mainF.getRight().getGraphics());
			}
		} else {
			mainF.getRight().getBtnNewButton().setName("Expand");
			mainF.getRight().setPreferredSize(new Dimension(50, 690));
			mainF.getRight().getBtnNewButton()
					.setIcon(mainF.getModel().getVariables().getImgExpand());
			mainF.getRight().getBtnNewButton().setBounds(10, 11, 30, 30);
		}
		mainF.getRight().addAll();
		mainF.pack();
	}
	// Method that creates a new house with its selected equipments
	public void createNewHouse() {
		int houseId = modelClass.getHighestHouseId();
		String houseName = "Greenhouse " + houseId;
		int sections = mainF.getCenter().getCenterNewHouse()
				.getSliderSections().getValue();
		modelClass.addHouse(houseId, houseName, true);
		modelClass.getHouseName(houseName).setAutoClimateControl(
				mainF.getCenter().getCenterNewHouse()
						.getChckActiveCoolingCheck().isSelected());

		int sectionId = modelClass.getHighestSectionId();
		ArrayList<Section> tempSections = new ArrayList<Section>();
		for (int i = 1; i <= sections; i++) {
			Section tempSection = new Section(modelClass, sectionId, houseId,
					"Section " + sectionId);
			tempSections.add(tempSection);
			sectionId++;
		}
		// Add sections to the house
		modelClass.getHouseName(houseName).addSections(tempSections, true);
		//Sets house equipment
		if (mainF.getCenter().getCenterNewHouse().getChckActiveCoolingCheck()
				.isSelected()) {
			EqActiveCooling actCool = new EqActiveCooling();
			modelClass.getHouseName(houseName).addEquipment(actCool, true);
		}
		if (mainF.getCenter().getCenterNewHouse().getChckCo2Check()
				.isSelected()) {
			EqCO2 co2 = new EqCO2();
			modelClass.getHouseName(houseName).addEquipment(co2, true);
		}
		if (mainF.getCenter().getCenterNewHouse().getChckCurtainsCheck()
				.isSelected()) {
			EqCurtain curtain = new EqCurtain();
			modelClass.getHouseName(houseName).addEquipment(curtain, true);
		}
		if (mainF.getCenter().getCenterNewHouse().getChckLightCheck()
				.isSelected()) {
			EqLight eqLight = new EqLight();
			modelClass.getHouseName(houseName).addEquipment(eqLight, true);
		}
		if (mainF.getCenter().getCenterNewHouse().getChckSprinklerCheck()
				.isSelected()) {
			EqSprinkler eqSprinkler = new EqSprinkler();
			modelClass.getHouseName(houseName).addEquipment(eqSprinkler, true);
		}
		if (mainF.getCenter().getCenterNewHouse().getChckTermostatCheck()
				.isSelected()) {
			EqTermostat eqTermostat = new EqTermostat();
			modelClass.getHouseName(houseName).addEquipment(eqTermostat, true);
		}
		if (mainF.getCenter().getCenterNewHouse().getChckWindowsCheck()
				.isSelected()) {
			EqWindow eqWindow = new EqWindow();
			modelClass.getHouseName(houseName).addEquipment(eqWindow, true);
		}

		showPanel("Houses");
	}

	// Method that decides what specific house-tile is pressed
	public void houseTilePressed(ActionEvent arg0) {
		int startIndex = arg0.getSource().toString().indexOf('[');
		int endIndex = arg0.getSource().toString().indexOf(',', startIndex);
		String name = arg0.getSource().toString()
				.substring(startIndex + 1, endIndex);
		mainF.getModel().setCurrentHouse(mainF.getModel().getHouseName(name));

		showPanel("Sections");
	}
	
	// Setting the view if a plant-tile is press
	public void plantTilePressed(ActionEvent arg0) {
		int startIndex = arg0.getSource().toString().indexOf('[');
		int endIndex = arg0.getSource().toString().indexOf(',', startIndex);
		String plantName = arg0.getSource().toString()
				.substring(startIndex + 1, endIndex);
		Plant tempPlant = mainF.getModel().getPlantName(plantName);
		Plant newPlant = new Plant(modelClass, tempPlant.getTypeID(),
				tempPlant.getName(), tempPlant.getOptCO2(),
				tempPlant.getOptTemp(), tempPlant.getOptFugt(),
				tempPlant.getOptLigt(), tempPlant.getPrice(),
				tempPlant.getPictureLocation());
		newPlant.setId(modelClass.getDb().getHighestPlantId());
		mainF.getModel().getCurrentSection().setPlant(newPlant, true);

		mainF.getCenter().getCenterConfigSection().getBtnDiscardPlants()
				.setEnabled(true);
		mainF.getCenter().getCenterConfigSection().getBtnSellPlants()
				.setEnabled(true);
		mainF.getCenter().getCenterConfigSection().getBtnAddPlants()
				.setEnabled(false);
		mainF.getCenter().getCenterConfigSection().repaint();

		showPanel("ConfigSection");
	}
	// Method that decides what specific-section tile is pressed
	public void sectionTilePressed(ActionEvent arg0) {
		int startIndex = arg0.getSource().toString().indexOf('[');
		int endIndex = arg0.getSource().toString().indexOf(',', startIndex);
		String name = arg0.getSource().toString()
				.substring(startIndex + 1, endIndex);
		Section tempSection = mainF.getModel().getCurrentHouse()
				.getSectionByName(name);

		mainF.getModel().setCurrentSection(tempSection);
		mainF.getCenter().getCenterConfigSection().UpdateLabels();
		showPanel("ConfigSection");
	}
	// Method that deletes plant from section
	public void discardPlant() {
		modelClass.getDb().deleteAddedPlant(
				modelClass.getCurrentSection().getPlant().getId());
		modelClass.getCurrentSection().setPlant(null, false);
		mainF.getCenter().getCenterConfigSection().UpdateLabels();
		mainF.getCenter().getCenterConfigSection().getBtnAddPlants()
				.setEnabled(true);
		mainF.getCenter().getCenterConfigSection().getBtnDiscardPlants()
				.setEnabled(false);
		mainF.getCenter().getCenterConfigSection().getBtnSellPlants()
				.setEnabled(false);

		showPanel("ConfigSection");
	}
	// Method that sells plant from section.
	public void sellPlant() {
		modelClass.getCurrentSection().setPlant(null, false);
		mainF.getCenter().getCenterConfigSection().UpdateLabels();
		mainF.getCenter().getCenterConfigSection().getBtnAddPlants()
				.setEnabled(true);
		mainF.getCenter().getCenterConfigSection().getBtnDiscardPlants()
				.setEnabled(false);
		mainF.getCenter().getCenterConfigSection().getBtnSellPlants()
				.setEnabled(false);

		showPanel("ConfigSection");

	}
	// Method the OpensWindows
	public void manuelOpenCloseWindows() {
		if (mainF.getCenter().getCenterSection().getChckWindows().isSelected()) {
			/*
			 * Active Cooling = 0; CO2 = 1; Curtain = 2; Light = 3; Sprinkler =
			 * 4; Termostates = 5; Windows = 6;
			 */
			boolean[] turnEquipments = new boolean[7];
			for (Equipment equip : modelClass.getCurrentHouse().getEquipments()) {
				if (equip.getName().equals("Active Cooling")) {
					turnEquipments[0] = equip.isOnOff();
				} else if (equip.getName().equals("CO2")) {
					turnEquipments[1] = equip.isOnOff();
				} else if (equip.getName().equals("Curtain")) {
					turnEquipments[2] = equip.isOnOff();
				} else if (equip.getName().equals("Light")) {
					turnEquipments[3] = equip.isOnOff();
				} else if (equip.getName().equals("Sprinkler")) {
					turnEquipments[4] = equip.isOnOff();
				} else if (equip.getName().equals("Termostats")) {
					turnEquipments[5] = equip.isOnOff();
				} else if (equip.getName().equals("Windows")) {
					turnEquipments[6] = true;
				}
			}
			manuelChangeHouseSettings(modelClass.getCurrentHouse(),
					turnEquipments);
			mainF.getCenter().getCenterSection().getLblWindowsOnOff()
					.setText("on");
			mainF.getCenter().getCenterSection().repaint();

		} else {
			/*
			 * Active Cooling = 0; CO2 = 1; Curtain = 2; Light = 3; Sprinkler =
			 * 4; Termostates = 5; Windows = 6;
			 */
			boolean[] turnEquipments = new boolean[7];
			for (Equipment equip : modelClass.getCurrentHouse().getEquipments()) {
				if (equip.getName().equals("Active Cooling")) {
					turnEquipments[0] = equip.isOnOff();
				} else if (equip.getName().equals("CO2")) {
					turnEquipments[1] = equip.isOnOff();
				} else if (equip.getName().equals("Curtain")) {
					turnEquipments[2] = equip.isOnOff();
				} else if (equip.getName().equals("Light")) {
					turnEquipments[3] = equip.isOnOff();
				} else if (equip.getName().equals("Sprinkler")) {
					turnEquipments[4] = equip.isOnOff();
				} else if (equip.getName().equals("Termostats")) {
					turnEquipments[5] = equip.isOnOff();
				} else if (equip.getName().equals("Windows")) {
					turnEquipments[6] = false;
				}
			}
			manuelChangeHouseSettings(modelClass.getCurrentHouse(),
					turnEquipments);
			mainF.getCenter().getCenterSection().getLblWindowsOnOff()
					.setText("off");
			mainF.getCenter().getCenterSection().repaint();
		}
	}
	
	//Method that changes label for sprinkler on/off
	public void manuelOnOffSprinkler() {
		if (mainF.getCenter().getCenterSection().getChckSprinklers()
				.isSelected()) {
			mainF.getCenter().getCenterSection().getLblSprinklersOnOff()
					.setText("on");
			mainF.getCenter().getCenterSection().repaint();

		} else {
			mainF.getCenter().getCenterSection().getLblSprinklersOnOff()
					.setText("off");
			mainF.getCenter().getCenterSection().repaint();
		}
	}
	// not fully implemented 
	public void automaticClimateControlForAllHouses() {
		if (mainF.getCenter().getCenterNewHouse().getChckAutoCli().isSelected()) {
			mainF.getCenter().getCenterNewHouse().getSliderQuality()
					.setEnabled(true);
			mainF.getCenter().getCenterNewHouse().getSliderEconomy()
					.setEnabled(true);
			mainF.getCenter().getCenterNewHouse().getSliderGrowthSpeed()
					.setEnabled(true);
			mainF.getCenter().getCenterNewHouse().getLblAutoOnOff()
					.setText("on");
			mainF.getCenter().getCenterNewHouse().getSliderEconomy()
					.setVisible(true);
			mainF.getCenter().getCenterNewHouse().getSliderQuality()
					.setVisible(true);
			mainF.getCenter().getCenterNewHouse().getSliderGrowthSpeed()
					.setVisible(true);
			mainF.getCenter().getCenterNewHouse().repaint();

		} else {
			mainF.getCenter().getCenterNewHouse().getSliderQuality()
					.setEnabled(false);
			mainF.getCenter().getCenterNewHouse().getSliderEconomy()
					.setEnabled(false);
			mainF.getCenter().getCenterNewHouse().getSliderGrowthSpeed()
					.setEnabled(false);
			mainF.getCenter().getCenterNewHouse().getLblAutoOnOff()
					.setText("off");
			mainF.getCenter().getCenterNewHouse().getSliderEconomy()
					.setVisible(false);
			mainF.getCenter().getCenterNewHouse().getSliderQuality()
					.setVisible(false);
			mainF.getCenter().getCenterNewHouse().getSliderGrowthSpeed()
					.setVisible(false);
			mainF.getCenter().getCenterNewHouse().repaint();
		}
	}

	public void setAutoClimateOnOffForSingleHouse() {
		if (mainF.getCenter().getCenterConfigHouse().getChckAutoCli()
				.isSelected()) {
			mainF.getCenter().getCenterConfigHouse().getSliderQuality()
					.setEnabled(true);
			mainF.getCenter().getCenterConfigHouse().getSliderEconomy()
					.setEnabled(true);
			mainF.getCenter().getCenterConfigHouse().getSliderGrowthSpeed()
					.setEnabled(true);
			mainF.getCenter().getCenterConfigHouse().getLblAutoOnOff()
					.setText("on");
			modelClass.getCurrentHouse().setAutoClimateControl(true);
			// mainF.getCenter().getCenterConfigHouse().repaint();

		} else {
			mainF.getCenter().getCenterConfigHouse().getSliderQuality()
					.setEnabled(false);
			mainF.getCenter().getCenterConfigHouse().getSliderEconomy()
					.setEnabled(false);
			mainF.getCenter().getCenterConfigHouse().getSliderGrowthSpeed()
					.setEnabled(false);
			mainF.getCenter().getCenterConfigHouse().getLblAutoOnOff()
					.setText("off");
			modelClass.getCurrentHouse().setAutoClimateControl(false);
			// mainF.getCenter().getCenterConfigHouse().repaint();
		}
	}
	
	//Method that changes on/off for auto generated data
	public void autoGenerateMeasOnOff() {
		if (mainF.getCenter().getCenterSettings().getChckbxOnOFF().isSelected()) {
			mainF.getCenter().getCenterSettings().getLblOnoff()
					.setText("Sensors");
			modelClass.setMainMindThread(new MainMindThread(modelClass));
		} else {
			mainF.getCenter().getCenterSettings().getLblOnoff()
					.setText("Auto-generated");
			modelClass.setMainMindThread(null);
		}
	}
	// Method that creates a plant
	public void createNewPlant() {
		int optCO2 = mainF.getCenter().getCenterNewPlant().getSliderCO2()
				.getValue();
		int optLight = mainF.getCenter().getCenterNewPlant().getSliderLight()
				.getValue();
		int optHumidity = mainF.getCenter().getCenterNewPlant()
				.getSliderHumidity().getValue();
		int optTemp = mainF.getCenter().getCenterNewPlant()
				.getSliderTemperature().getValue();
		int price = mainF.getCenter().getCenterNewPlant().getSliderPrice()
				.getValue();
		int prodState = 0;
		String name = mainF.getCenter().getCenterNewPlant().getTextNamePlant()
				.getText();
		int id = modelClass.getDb().getHighestPlantId();
		Plant plant = new Plant(modelClass, id, name, optCO2, optTemp,
				optHumidity, optLight, price, "noPicture");

		modelClass.addPlant(plant, true);
		showPanel("Houses");
	}

	public void configHouseAlarmCO2() {
		if (mainF.getCenter().getCenterSettings().getChckbxAlarmCo2()
				.isSelected()) {
			mainF.getCenter().getCenterSettings().getSliderAlarmCO2()
					.setEnabled(true);
			mainF.getCenter().getCenterSettings().getChckbxAlarmCo2()
					.setIcon(variables.getChkboxPressed());
		} else {
			mainF.getCenter().getCenterSettings().getSliderAlarmCO2()
					.setEnabled(false);
			mainF.getCenter().getCenterSettings().getSliderAlarmCO2()
					.setValue(100);
			mainF.getCenter().getCenterSettings().getChckbxAlarmCo2()
					.setIcon(variables.getChkboxDefault());
		}
	}

	public void configHouseAlarmLight() {
		if (mainF.getCenter().getCenterSettings().getChckbxAlarmLight()
				.isSelected()) {
			mainF.getCenter().getCenterSettings().getSliderAlarmLight()
					.setEnabled(true);
			mainF.getCenter().getCenterSettings().getChckbxAlarmLight()
					.setIcon(variables.getChkboxPressed());
		} else {
			mainF.getCenter().getCenterSettings().getSliderAlarmLight()
					.setEnabled(false);
			mainF.getCenter().getCenterSettings().getSliderAlarmLight()
					.setValue(100);
			mainF.getCenter().getCenterSettings().getChckbxAlarmLight()
					.setIcon(variables.getChkboxDefault());
		}
	}

	public void configHouseAlarmHumidity() {
		if (mainF.getCenter().getCenterSettings().getChckbxAlarmHumidity()
				.isSelected()) {
			mainF.getCenter().getCenterSettings().getSliderAlarmHumi()
					.setEnabled(true);
			mainF.getCenter().getCenterSettings().getChckbxAlarmHumidity()
					.setIcon(variables.getChkboxPressed());
		} else {
			mainF.getCenter().getCenterSettings().getSliderAlarmHumi()
					.setEnabled(false);
			mainF.getCenter().getCenterSettings().getChckbxAlarmHumidity()
					.setIcon(variables.getChkboxDefault());
			mainF.getCenter().getCenterSettings().getSliderAlarmHumi()
					.setValue(100);
		}
	}

	public void configHouseAlarmTemp() {
		if (mainF.getCenter().getCenterSettings().getChckbxAlarmTemperature()
				.isSelected()) {
			mainF.getCenter().getCenterSettings().getChckbxAlarmTemperature()
					.setIcon(variables.getChkboxPressed());
			mainF.getCenter().getCenterSettings().getSliderAlarmTemp()
					.setEnabled(true);
		} else {
			mainF.getCenter().getCenterSettings().getSliderAlarmTemp()
					.setEnabled(false);
			mainF.getCenter().getCenterSettings().getChckbxAlarmTemperature()
					.setIcon(variables.getChkboxDefault());
			mainF.getCenter().getCenterSettings().getSliderAlarmTemp()
					.setValue(100);
		}
	}

	public void configHouseSectionEmpty() {
		if (mainF.getCenter().getCenterSettings().getChckbxSectionEmpty()
				.isSelected()) {
			mainF.getCenter().getCenterSettings().getChckbxSectionEmpty()
					.setIcon(variables.getChkboxPressed());
		} else {
			mainF.getCenter().getCenterSettings().getChckbxSectionEmpty()
					.setIcon(variables.getChkboxDefault());
		}
	}

	public void configHousePlantFinished() {
		if (mainF.getCenter().getCenterSettings().getChckbxPlantFinnished()
				.isSelected()) {
			mainF.getCenter().getCenterSettings().getChckbxPlantFinnished()
					.setIcon(variables.getChkboxPressed());
		} else {
			mainF.getCenter().getCenterSettings().getChckbxPlantFinnished()
					.setIcon(variables.getChkboxDefault());
		}
	}

	
	
	
	public void runACycle(){
		Measurement measurement = null;
		if(modelClass.getMainMindThread()!=null){
			int light = modelClass.getMainMindThread().getLight();
			measurement = new Measurement(light);
		}else{
			Random r = new Random();
			measurement = new Measurement(r.nextInt(50)+5);
		}
		modelClass.addMeasurements(measurement);
		boolean[] turnEquipments;
		for(House house:modelClass.getHouses()){
			house.setOptimalMeas();
			if(house.isAutoClimateControl()){
			turnEquipments = BestSolution.calcBestSolution(house, measurement);
			house.turnEuipments(turnEquipments);
			}
			house.calcRunningCost();
			house.addRunningCostToTotalCost(house.getRunningCost());
			house.setCurrentMeas(measurement);
			for(Section section:house.getSections()){
				section.checkAlarmEmptyNotiFication(house.getCurrentTemp(), house.getCurrentLight(),
						house.getCurrentCO2(), house.getCurrentHumidity());
				if(section.getPlant()!=null){
				section.getPlant().updateProdstate(house.getCurrentTemp(), house.getCurrentLight(), house.getOptCO2(), house.getCurrentHumidity());
				}
			}
			house.checkAlarmEmptyNotiFication();
			
			
		}
		updateViews();
		if(modelClass.getMainMindThread()!=null){
			synchronized (modelClass.getMainMindThread()) {
				modelClass.getMainMindThread().configHouse(modelClass.getHouses().get(0));
			}
		}
	}
	
	public void updateViews(){
		if(mainF.getCenter()!=null){
		if(modelClass.getCurrentHouse()!=null){
			for(Equipment eQ : modelClass.getCurrentHouse().getEquipments()){
			if(eQ.getName().equals("Windows")){
				mainF.getCenter().getCenterSection().getChckWindows().setSelected(eQ.isOnOff());
			}
		}
		
		mainF.getCenter().getCenterConfigSection().repaint();
		mainF.getCenter().getCenterConfigSection().UpdateLabels();
		mainF.getCenter().getCenterHouse().getWeatherPanel().repaint();
		mainF.getCenter().getCenterHouse().getWeatherPanel().revalidate();
		mainF.getCenter().getCenterSection().updateLabels();
		}
		}
	}
	// Method for changing a house settings
	public void manuelChangeHouseSettings(House house, boolean[] turnEquipments){
		house.turnEuipments(turnEquipments);
		
		house.calcRunningCost();
		house.addRunningCostToTotalCost(house.getRunningCost());
		
		house.setCurrentMeas(modelClass.getMeasurements().get(modelClass.getMeasurements().size()-1));
		for(Section section:house.getSections()){
			section.checkAlarmEmptyNotiFication(house.getCurrentTemp(), house.getCurrentLight(),
					house.getCurrentCO2(), house.getCurrentHumidity());
			if(section.getPlant()!=null){
			section.getPlant().updateProdstate(house.getCurrentTemp(), house.getCurrentLight(), house.getOptCO2(), house.getCurrentHumidity());
			}
		}
		house.checkAlarmEmptyNotiFication();
		updateViews();
		if(modelClass.getMainMindThread()!=null){
		synchronized (modelClass.getMainMindThread()) {
			modelClass.getMainMindThread().configHouse(modelClass.getHouses().get(0));
		}
		
		}
	}
	
	
	// Method the sets a panel
	public void showPanel(String panel) {
		mainF.getCenter().show(panel);

		switch (panel) {
		case "Houses":
			mainF.getCenter().getCenterHouse().addHouses();
			break;
		case "Sections":
			mainF.getCenter().getCenterSection().addSections();
			mainF.getCenter().getCenterSection().updateLabels();
			break;
		case "ConfigSection":
			mainF.getCenter().getCenterConfigSection().UpdateLabels();
			mainF.getCenter().getCenterConfigSection().repaint();
			break;
		case "ConfigHouse":
			mainF.getCenter().getCenterConfigHouse().updatePanels();
			break;
		case "AddPlant":
			mainF.getCenter().getCenterAddPlant().addPlants();
			break;
		case "StatsPanel":
			mainF.getCenter().getCenterStatsPanel().refreshAll();
			break;
		}

	}

	public void backward() {
		mainF.getCenter().back();
	}

}
